﻿using System;
using System.Reactive.Subjects;
using System.Reactive.Linq;
using System.Windows.Forms;

namespace Demo
{
    public partial class EventsForm : Form
    {

        public EventsForm()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            ProcessEvents();
            listBox1.Items.Add("-----------------");
            ProcessObservables();
        }

        public event Action<int> MyEvent;
        private void ProcessEvents()
        {

            //MyEvent += (x => listBox1.Items.Add(x));
            MyEvent += new Action<int>(EventsForm_MyEvent);

            var myLocalEvent = MyEvent;  //avoid race conditions
            myLocalEvent(1);
            myLocalEvent(2);
            myLocalEvent(3);
        }

        void EventsForm_MyEvent(int obj)
        {
            throw new NotImplementedException();
        }

        private void ProcessObservables()
        {
            var MySubject = new Subject<int>();
            var s = MySubject.Subscribe(x => listBox1.Items.Add(x));

            MySubject.OnNext(4);
            MySubject.OnNext(5);
            MySubject.OnNext(6);
        }

    }

    //back to ppt
































    //Differences between Events and Subject (IObservable + IObserver)

    //  - Observables are First Class
    //    - stored in var, passed & returned, ** created at runtime **
    //    - Event is just a delegate - must be created at design time
    //    - Observable is a class and can be created at any time.

    //  - Observable has defined lifetime of stream 
    //    - void OnNext(T value);
    //    - void OnError(Exception error);
    //    - void OnCompleted();
    //    - no need for "flag values" in stream
            //MySubject.Subscribe(
            //    (x => listBox1.Items.Add(x)),
            //    (y => listBox1.Items.Add("Error")),
            //    (() => listBox1.Items.Add("Completed")));

    //  - single observable messages will not overlap in time

    //  - Subscribe returns IDisposable
    //    - cannot unsubscribe - you dispose
    //    - don't have to use delegates - can use anonymous method
    //    - can unsubscribe in different place than subscribed by Disposing

    //  - Compositional (therefore Linq-able)
    //    - Challenge 1
}
